package com.dc.schedule.api.base;

import com.dc.schedule.api.exception.ResponseTimeoutException;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * <p>Descriptions...
 *
 * @author Diamon.Cheng
 * @date 2022/7/27.
 */
public class WaitResponseLock<T> {
    private Integer waitResponseTimeoutSeconds = 10;
    private final Lock lock = new ReentrantLock();
    private final Condition responseSet = lock.newCondition();
    private T response;
    
    public WaitResponseLock<T> setWaitResponseTimeoutSeconds(Integer waitResponseTimeoutSeconds) {
        this.waitResponseTimeoutSeconds = waitResponseTimeoutSeconds;
        return this;
    }
    
    public void setResponse(T response) {
        lock.lock();
        try {
            this.response = response;
            responseSet.signal();
        } finally {
            lock.unlock();
        }
        
    }
    
    public T getResponse() {
        lock.lock();
        try {
            while (this.response == null) {
                try {
                    final boolean ok = responseSet.await(waitResponseTimeoutSeconds, TimeUnit.SECONDS);
                    if (!ok) {
                        throw new ResponseTimeoutException("等待服务器响应超时, 等待时间: " + waitResponseTimeoutSeconds + "S");
                    }
                } catch (InterruptedException ignored) {
        
                }
            }
        } finally {
            lock.unlock();
        }
        return this.response;
    }
}
